package com.wd.good.aspect;

import com.wd.good.annotation.MyRetryable;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @description: 重试Aspect
 * @author wangdpng
 * @date 2023/11/18 20:00
 */
@Slf4j
@Aspect
@Component
public class RetryAspect {

    @Pointcut("@annotation(com.wd.good.annotation.MyRetryable)")
    private void retryMethodCall(){}

    @Around("retryMethodCall()")
    public void retry(ProceedingJoinPoint joinPoint){
        MyRetryable myRetryable = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(MyRetryable.class);
        int retryTimes = myRetryable.retryTimes();
        int retryInterval = myRetryable.retryInterval();

        for(int i = 1; i <= retryTimes; i++) {
            try {
                joinPoint.proceed(); // 这个面试曾经问到过
                return;
            } catch (Throwable e) {
                log.error("调用发生异常，开始重试，retryTimes:{}", i);
            }
            try {
                Thread.sleep(retryInterval*1000L);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        throw new RuntimeException("重试次数耗尽");
    }
}
